package com.wht.media.controller;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.aizuda.zlm4j.callback.IMKWebRtcGetAnwerSdpCallBack;
import com.wht.media.config.MediaServerConfig;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.*;
import org.noear.solon.core.handle.Context;
import org.smartboot.http.common.enums.HttpStatus;

import java.io.IOException;

import static com.wht.media.context.MediaServerContext.ZLM_API;


/**
 * WebRtc信令模块
 *
 * @author by HaiTao.Wang on 2025/9/12.
 */
@Slf4j
@Controller
@Mapping("webrtc")
public class WebRtcController {

    @Inject
    MediaServerConfig config;

    @Inject("${server.port}")
    private int port;

    /**
     * webrtc sdp协议交互
     *
     * @param app    应用名称
     * @param stream 流标识
     * @param type   sdp协议动作类型：play、push、echo
     * @param pcSdp  前端请求的sdp协议
     * @throws IOException
     */
    @Mapping
    public void webrtc(Context ctx, String app, String stream, String type, @Body String pcSdp) throws IOException {
        //webrtc使用的是udp,默认监听8000,不需要设置端口号
        String rtcUrl = StrUtil.format("rtc://{}:{}/{}/{}", config.getRtcHost(), config.getRtcPort(), app, stream);
        IMKWebRtcGetAnwerSdpCallBack imkWebRtcGetAnwerSdpCallBack = createWebrtcAnswerSdpCallback(ctx);
        ZLM_API.mk_webrtc_get_answer_sdp(null, imkWebRtcGetAnwerSdpCallBack, type, pcSdp, rtcUrl);
    }

    /**
     * 构建服务端SDP协议回调对象
     *
     * @param ctx 上下文对象
     * @return
     */
    private static IMKWebRtcGetAnwerSdpCallBack createWebrtcAnswerSdpCallback(Context ctx) {
        return (pointer, sevSdp, error) -> {
            JSONObject result = new JSONObject();
            if (StrUtil.isNotBlank(error)) {
                log.error("zkMediaKit 交互 webrtc 协议失败！");
                result.putOnce("code", -1).putOnce("sdp", null);
            } else {
                log.info("zkMediaKit 交互 webrtc 协议成功！");
                result.putOnce("code", 0).putOnce("sdp", sevSdp);
            }
            try {
                ctx.status(HttpStatus.OK.value());
                ctx.contentType("application/json");
                ctx.output(result.toString());
            } catch (Exception e) {
                log.error("返回webrtc结果失败", e);
            }
        };
    }


    /**
     * 推流sdp交互
     *
     * @param app
     * @param stream
     */
    @Mapping("whip")
    public void whip(String app, String stream, @Body String offerSdp, Context context) {
        //这里可以做鉴权
        String authorization = context.header("Authorization");

        //webrtc使用的是udp,默认监听8000,不需要设置端口号
        String rtcUrl = StrUtil.format("rtc://{}:{}/{}/{}", config.getRtcHost(), config.getRtcPort(), app, stream);
        IMKWebRtcGetAnwerSdpCallBack imkWebRtcGetAnwerSdpCallBack = (pointer, sdp, s1) -> {
            //todo 如果是https请换为https
            String location = StrUtil.format("http://{}:{}/webrtc/delete?id={}&token={}", config.getRtcHost(), port, "whip_" + stream, RandomUtil.randomString(8));
            context.contentType("application/sdp");
            context.headerSet("Location", location);
            context.status(201);
            context.output(sdp);
        };
        ZLM_API.mk_webrtc_get_answer_sdp(null, imkWebRtcGetAnwerSdpCallBack, "push", offerSdp, rtcUrl);
    }

    /**
     * 拉流sdp交互
     *
     * @param app
     * @param stream
     */
    @Post
    @Mapping("whep")
    public void whep(String app, String stream, @Body String offerSdp, Context context) {

        String rtcUrl = StrUtil.format("rtc://{}:{}/{}/{}", config.getRtcHost(), config.getRtcPort(), app, stream);

        IMKWebRtcGetAnwerSdpCallBack imkWebRtcGetAnwerSdpCallBack = (pointer, sdp, s1) -> {
            //todo 如果是https请换为https
            String location = StrUtil.format("http://{}:{}/webrtc/delete?id={}&token={}", config.getRtcHost(), port, "whip_" + stream, RandomUtil.randomString(8));
            context.contentType("application/sdp");
            context.headerSet("Location", location);
            context.status(201);
            context.output(sdp);
        };

        ZLM_API.mk_webrtc_get_answer_sdp(null, imkWebRtcGetAnwerSdpCallBack, "play", offerSdp, rtcUrl);
    }

    /**
     * 删除webrtc
     * 要显式终止会话，WHEP 播放器必须对初始HTTP POST的Location头字段中返回的资源URL执行HTTP DELETE请求。收到HTTP DELETE请求后，WHEP资源将被删除，并在媒体服务器上释放资源
     *
     * @param id
     * @param token
     */
    @Delete
    @Mapping("delete")
    public void deleteWebrtc(String id, String token, Context context) {

        //todo 校验token后删除资源

        context.status(200);
        context.output("");
    }
}
